/*
 * Copyright 2008 by Emeric Vernat
 *
 *     This file is part of MSwing.
 *
 * MSwing is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MSwing is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with MSwing.  If not, see <http://www.gnu.org/licenses/>.
 */
package mswing.table;

import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;

import javax.swing.JRootPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;

/**
 * Scrolling avec bouton du milieu de la souris.
 *
 * @author Santhosh Kumar T (MySwing)
 */
final class MScrollGestureRecognizer implements AWTEventListener {
	private static final MScrollGestureRecognizer INSTANCE = new MScrollGestureRecognizer();

	private MScrollGestureRecognizer() {
		start();
	}

	static MScrollGestureRecognizer getInstance() {
		return INSTANCE;
	}

	void start() {
		Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
	}

	void stop() {
		Toolkit.getDefaultToolkit().removeAWTEventListener(this);
	}

	/** {@inheritDoc} */
	public void eventDispatched(AWTEvent event) {
		final MouseEvent me = (MouseEvent) event;
		final boolean isGesture = SwingUtilities.isMiddleMouseButton(me)
				&& me.getID() == MouseEvent.MOUSE_PRESSED;
		if (!isGesture) {
			return;
		}

		Component comp = me.getComponent();
		comp = SwingUtilities.getDeepestComponentAt(comp, me.getX(), me.getY());
		final JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class,
				comp);
		if (viewPort == null || !MScrollGlassPane.canScroll(viewPort)) {
			return;
		}
		viewPort.getViewSize();

		final JRootPane rootPane = SwingUtilities.getRootPane(viewPort);
		if (rootPane == null) {
			return;
		}
		final Point location = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(),
				rootPane.getGlassPane());
		final MScrollGlassPane glassPane = new MScrollGlassPane(rootPane.getGlassPane(), viewPort,
				location);
		rootPane.setGlassPane(glassPane);
		glassPane.setVisible(true);

		try {
			final Robot robot = new Robot();
			robot.mouseRelease(InputEvent.BUTTON2_MASK);
			robot.mousePress(InputEvent.BUTTON2_MASK);
		} catch (final AWTException ignore) {
			glassPane.movingTimer.start();
		}
	}
}
